;
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                         (c) Copyright 2002, Jean J. Labrosse, Weston, FL
;                                          All Rights Reserved
;
;
;                                  PIC24FJ Board Support Package
;                                                 
;
; File         : bsp_a.s
; By           : Eric Shufro
;********************************************************************************************************
;

;
;********************************************************************************************************
;                                                CONSTANTS
;********************************************************************************************************
;
    .equ     __24FJ256GB110, 1                      ; Inform the p24FJ256GB110 header file that we are using a p24FJ256GB110
    
;
;********************************************************************************************************
;                                                INCLUDES
;********************************************************************************************************
;

    .include "p24FJ256GB110.inc"                    ; Include assembly equates for various CPU registers and bit masks
    .include "os_cpu_util_a.s"                      ; Include an assembly utility files with macros for saving and restoring the CPU registers

;
;********************************************************************************************************
;                                             LINKER SPECIFICS
;********************************************************************************************************
;

    .text                                           ; Locate this file in the text region of the build

;
;********************************************************************************************************
;                                                 GLOBALS
;********************************************************************************************************
;

	.global __T2Interrupt
	.global __T4Interrupt
	.global __U1TXInterrupt
	.global __U1RXInterrupt
    
;
;********************************************************************************************************
;                                            OS Time Tick ISR Handler
;
; Description : This function services the OS Time Tick Interrupt when configured using Timer #2
;
; Notes       : All user interrupts should be defined as follows.
;********************************************************************************************************
;

__T2Interrupt:
    OS_REGS_SAVE                                    ; 1) Save processor registers
    
;    inc.b _OSIntNesting                            ; 2) Call OSIntEnter() or increment OSIntNesting
    call _OSIntEnter	                            ; 2) Call OSIntEnter() or increment OSIntNesting
        
    dec.b _OSIntNesting, wreg                       ; 3) Check OSIntNesting. if OSIntNesting == 1, then save the stack pointer, otherwise jump to T2_Cont
    bra nz, T2_Cont
    mov _OSTCBCur, w0
    mov w15, [w0]    

T2_Cont:  
    bclr  IFS0, #T2IF                               ; 4) Clear the interrupt source

    call _OS_Tick_ISR_Handler                       ; 5) Call YOUR ISR Handler (May be a C function). In this case, the OS Tick ISR Handler
    call _OSIntExit                                 ; 6) Call OSIntExit() or decrement 1 from OSIntNesting
    
    OS_REGS_RESTORE                                 ; 7) Restore registers

    retfie                                          ; 8) Return from interrupt


;
;********************************************************************************************************
;                                            OS Time Tick ISR Handler
;
; Description : This function services the OS Time Tick Interrupt when configured using Timer #4
;
; Notes       : All user interrupts should be defined as follows.
;********************************************************************************************************
;

__T4Interrupt:
    OS_REGS_SAVE                                   ; 1) Save processor registers
    
    inc.b _OSIntNesting                            ; 2) Call OSIntEnter() or increment OSIntNesting
        
    dec.b _OSIntNesting, wreg                      ; 3) Check OSIntNesting. if OSIntNesting == 1, then save the stack pointer, otherwise jump to T2_Cont
    bra nz, T4_Cont    
    mov _OSTCBCur, w0
    mov w15, [w0]    

T4_Cont:  
    bclr  IFS1, #T4IF                              ; 4) Clear the interrupt source
    
    call _OS_Tick_ISR_Handler                      ; 5) Call YOUR ISR Handler (May be a C function). In this case, the OS Tick ISR Handler
    call _OSIntExit                                ; 6) Call OSIntExit() or decrement 1 from OSIntNesting
    
    OS_REGS_RESTORE                                ; 7) Restore registers

    retfie                                         ; 8) Return from interrupt


;
;********************************************************************************************************
;                                            UART 1 TX ISR Handler
;
; Description : This function services the OS Time Tick Interrupt when configured using Timer #4
;
; Notes       : All user interrupts should be defined as follows.
;********************************************************************************************************
;
__U1TXInterrupt:
	bclr IFS0, #U1TXIF
	retfie

;
;********************************************************************************************************
;                                            UART 1 RX ISR Handler
;
; Description : This function services the OS Time Tick Interrupt when configured using Timer #4
;
; Notes       : All user interrupts should be defined as follows.
;********************************************************************************************************
;
__U1RXInterrupt:
	mov.d w0,[w15++]								; 1) Save processor registers
	push PSVPAG
	inc.b _OSIntNesting								; 2) Increment OSIntNesting

    dec.b _OSIntNesting, wreg						; 3) Check OSIntNesting. if OSIntNesting == 1, then save the stack pointer, otherwise jump to T2_Cont
    bra nz, U1RX_Cont
    mov _OSTCBCur, w0
    mov w15, [w0]

U1RX_Cont:
	bclr IFS0, #U1RXIF								; 4) Clear the interrupt source

	mov.w U1RXREG,w0
	mov.w _Fifo_W,w1
	mov.b w0,[w1]
	
;;	mov.w _Fifo_W,w1
	mov.w _Fifo_E,w0
	sub.w w1,w0,[w15]
	bra geu, To_Else
	inc.w _Fifo_W
	mov.w _Fifo_W,w1
	bra To_Next
To_Else:
;	inc.w w1,w0
	mov.w _Fifo_S,w1
	mov.w w1,_Fifo_W
To_Next:
;	mov.w _Fifo_W,w1
	mov.w _Fifo_R,w0
	sub.w w1,w0,[w15]
	bra nz, To_End
	inc.w _Fifo_R

To_End:
	dec.b _OSIntNesting								; 5) Decrement 1 from OSIntNesting

	pop PSVPAG									; 6) Restore registers
	mov.d [--w15],w0
	retfie											; 7) Return from interrupt
